package descentFly.away3D4.net {
	//	import com.adobe.serialization.json.JSON;
	
	import UIFree.ObjectEvent;
	import UIFree.uif_Timer;
	
	import descentFly.away3D4.chips.df_chipAway;
	import descentFly.df_utils;
	
	import flash.errors.IOError;
	import flash.events.*;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	import flash.net.Socket;
	
	import org.osmf.events.TimeEvent;
	
	
	public class mySocket extends Socket {
		public static const RESPONSE_JSON		: String = 'RESPONSE_JSON';
		public static const RESPONSE_STRING		: String = 'RESPONSE_STRING';
		public static const RESPONSE_NOTIFY		: String = 'RESPONSE_NOTIFY';
		
		public static const NF_INITIALIZE		: String = 'INITIALIZE';
		public static const NF_DISPOSE			: String = 'DISPOSE';
		public static const NF_UPDATEKS			: String = 'UPDATEKS';
		public static const NF_SENDCHAT			: String = 'SENDCHAT';
		public static const NF_DESTRUCTION		: String = 'DESTRUCTION';
		public static const NF_TIMER			: String = 'TIMER';
		public static const NF_POINTSSTATE		: String = 'POINTSSTATE';
		public static const NF_ACTIVESTATE		: String = 'ACTIVESTATE';
		
		private var _uid		: uint;
		private var _session	: int;
		private var _retFunc	: Object;
		private var _chip		: df_chipAway;
		
		public function mySocket(uid		: uint, 
								 session	: int,
								 host		: String = null, 
								 port		: uint = 0) {
			super(host, port);
			_retFunc 	= new Object();
			_uid 		= uid;
			_session 	= session;
			configureListeners();
		}
		
		public function closeConnection(): void {
			if (connected) {
				writeUTFBytes("shutdown;");
				flush();
			}
		}
		
		public function updateAction(actionName: String, set: Object): void {
			sendObject({
				method	: 'action',
				params	: {
					action	: actionName,
					value	: set,
					matrix	: df_utils.matToArray(_chip.body.skin.transform),
					live	: _chip.live
				}
			})
		}
		
		public function destructionMyChip(killerUID: String): void {
			sendObject({
				method	: 'destructionMyChip',
				params	: {
					killer: killerUID
				}
			})
		}
		
		public function getSessionState(ret: Function): void {
			getData('getState', null, ret);
		}
		
		public function refresh(matrix: Matrix3D, ret: Function): void {
			getData('refresh', df_utils.matToArray(matrix), ret);
		}
		
		private function configureListeners():void {
			addEventListener(Event.CONNECT, connectHandler);
			addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
		}
		
		public function sendObject(object: Object): void {
			if (connected) {
				writeUTFBytes(JSON.stringify(object) + ';');
				flush();
			}
		}
		
		private function responseJSON(json: String): void {
			var data: Object = JSON.parse(json);
			if (data.hasOwnProperty('qid') && _retFunc.hasOwnProperty(data.qid)) { // Это ответ на запрос
				_retFunc[data.qid](data.result);
				delete(_retFunc[data.qid]);
			} else if (data.hasOwnProperty('notify')) 
				doNotify(data);
			dispatchEvent(new ObjectEvent(RESPONSE_JSON, data));
		}
		
		protected function doNotify(data: Object): void {
			dispatchEvent(new ObjectEvent(RESPONSE_NOTIFY, data));
		}
		
		private function responseString(data: String): void {
			dispatchEvent(new ObjectEvent(RESPONSE_STRING, data));
		}
		
		private function readResponse():void {
			var parts: Array = readUTFBytes(bytesAvailable).split(';');
			parts.forEach(function(item: String, i: int, arr: Array): void {
				if (item) {
					if (item.substr(0, 1) == '{')
						responseJSON(item);
					else responseString(item);
				}
			});
		}
		
		protected function qidGenerate(): String {
			return (Math.random() * uint.MAX_VALUE).toString(16);
		}
		
		protected function getData(a_method: String, params: Object, retFunc: Function): void {
			var a_qid: String = qidGenerate();
			_retFunc[a_qid] = retFunc;
			sendObject({
				method	: a_method,
				qid		: a_qid,
				params	: params
			})
		}
		
		public function initChip(a_chip	: df_chipAway): void {
			_chip = a_chip;
			getData('init', {
				uid			: _uid,
				session		: _session,
				matrix		: df_utils.matToArray(_chip.body.skin.transform),
				live		: _chip.live,
				keyState	: _chip.keyState
			}, doCompleteInit)
		}
		
		protected function doCompleteInit(data: Object): void {
			dispatchEvent(new ObjectEvent(Event.COMPLETE, data));
		}
		
		private function connectHandler(event:Event):void {
//			init();
		}
		
		private function ioErrorHandler(event:IOErrorEvent):void {
			trace("ioErrorHandler: " + event);
		}
		
		private function securityErrorHandler(event:SecurityErrorEvent):void {
			trace("securityErrorHandler: " + event);
		}
		
		private function socketDataHandler(event:ProgressEvent):void {
			readResponse();
		}		
	}
}